// 函数式编制之以函数作为返回值
object Demo10Func4 {
  def printHello(): Unit = {
    println("Hello")
  }

  /**
   * 以函数作为返回值时 需要手动声明返回值的类型
   */
  def func1(str: String): Int => Int = {
    def func1_1(i: Int): Int = {
      str.toInt + i
    }

    func1_1
  }

  // 简化定义
  // 柯里化：将一个有N个参数的函数 变成 N个只有一个参数的函数
  // func3 --> func2 从一个有两个参数的函数-->两个只有一个参数的函数
  def func2(str: String)(i: Int): Int = {
    str.toInt + i
  }

  def func3(str: String, i: Int): Int = {
    str.toInt + i
  }
  // 计算a的b次方，如果b没有指定 则默认计算a的3次方
  // 函数名为 aPowerB

  /**
   * aPowerB(2,3)
   * aPowerB(2,4)
   * aPowerB(3,4)
   * aPowerB(3)
   *
   */

  // 第一种方式：默认参数
  def aPowerB(a: Int, b: Int = 3): Unit = {
    println(Math.pow(a, b))
  }

  // 第二种方式
  def aPowerB2(b: Int)(a: Int): Unit = {
    println(Math.pow(a, b))
  }

  // 函数可以在object中、class中、方法中定义
  def main(args: Array[String]): Unit = {
    def printWorld(): Unit = {
      println("World")
    }

    Demo10Func4.printHello()
    printWorld()

    // 函数的调用
    val intToIntFunc: Int => Int = func1("10")
    val i: Int = intToIntFunc(100)
    println(i) // 110
    // 简化调用
    println(func1("10")(100))

    println(func2("200")(100)) // 300

    aPowerB(2, 3)
    aPowerB(2, 4)
    aPowerB(3, 4)
    aPowerB(3)

    // 偏应用函数：将有N个参数的函数 变成 N-X个参数的函数 ，X即为固定的参数
    aPowerB2(2)(3)
    aPowerB2(2)(4)
    aPowerB2(2)(5)
    aPowerB2(2)(6)
    aPowerB2(2)(7)

    val a2PowerB: Int => Unit = aPowerB2(2)
    a2PowerB(4)
    a2PowerB(5)
    a2PowerB(6)
    a2PowerB(7)
  }

}
